package org.yaac.client.ui;

import java.util.Collection;
import java.util.Date;
import java.util.List;

import org.yaac.client.ui.StatisticsView.Presenter;

import com.google.gwt.view.client.ProvidesKey;

/**
 * @author Max Zhu (thebbsky@gmail.com)
 *
 */
public interface StatisticsView extends YaacView<Presenter> {
	
	/**
	 * @author Max Zhu (thebbsky@gmail.com)
	 *
	 */
	public interface Presenter {

		void onFilterChange(String selectedNamespace, String selectedKind);
		
	}

	/**
	 * overall status to be displayed in top menu
	 * 
	 * @author Max Zhu (thebbsky@gmail.com)
	 *
	 */
	public static class Summary {
		
		/**
		 * last updated time in GMT
		 */
		private Date date;
		
		/**
		 * 
		 */
		private Long noEntities;
		
		/**
		 * 
		 */
		private Long sizeEntities;

		public Summary(Date date, Long noEntities, Long sizeEntities) {
			super();
			this.date = date;
			this.noEntities = noEntities;
			this.sizeEntities = sizeEntities;
		}

		public Date getDate() {
			return date;
		}

		public Long getNoEntities() {
			return noEntities;
		}

		public Long getSizeEntities() {
			return sizeEntities;
		}
	}
	
	/**
	 * @author Max Zhu (thebbsky@gmail.com)
	 *
	 */
	public static class PropertyTypeBreakdown {
		
		public static final ProvidesKey<PropertyTypeBreakdown> KEY_PROVIDER = new ProvidesKey<PropertyTypeBreakdown>() {
			@Override
			public Object getKey(PropertyTypeBreakdown item) {
				return item == null ? null : item.getPropertyType();
			}
		};
		
		private String propertyType;
		
		private Long bytes;
		
		private Long count;

		public PropertyTypeBreakdown(String propertyType) {
			super();
			this.propertyType = propertyType;
		}

		public String getPropertyType() {
			return propertyType;
		}

		public Long getBytes() {
			return bytes;
		}

		public Long getCount() {
			return count;
		}

		public void addBytes(Long bytes) {
			this.bytes = this.bytes == null ? bytes : this.bytes + bytes;
		}

		public void addCount(Long count) {
			this.count = this.count == null ? count : this.count + count;
		}
	}
	
	/**
	 * @author Max Zhu (thebbsky@gmail.com)
	 *
	 */
	public static class NamespaceBreakdown {
		
		public static final ProvidesKey<NamespaceBreakdown> KEY_PROVIDER = new ProvidesKey<NamespaceBreakdown>() {
			@Override
			public Object getKey(NamespaceBreakdown item) {
				return item == null ? null : item.getNamespace();
			}
		};
		
		private String namespace;
		
		private Long bytes;
		
		private Long count;
		
		public NamespaceBreakdown(String namespace) {
			super();
			this.namespace = namespace;
			this.bytes = 0l;
			this.count = 0l;
		}

		public String getNamespace() {
			return namespace;
		}

		public Long getBytes() {
			return bytes;
		}

		public Long getCount() {
			return count;
		}

		public void addBytes(Long bytes) {
			this.bytes = this.bytes == null ? bytes : this.bytes + bytes;
		}

		public void addCount(Long count) {
			this.count = this.count == null ? count : this.count + count;
		}
	}

	/**
	 * @author Max Zhu (thebbsky@gmail.com)
	 *
	 */
	public static class KindBreakdown {
	
		public static final ProvidesKey<KindBreakdown> KEY_PROVIDER = new ProvidesKey<KindBreakdown>() {
			@Override
			public Object getKey(KindBreakdown item) {
				return item == null ? null : item.getKindName();
			}
		};
		
		private String kindName;
		
		private Long count;
		
		private Long size;
		
		private Long rootCount;
		
		private Long rootSize;
		
		private Long nonRootCount;
		
		private Long nonRootSize;
		
		public KindBreakdown(String kindName) {
			super();
			this.kindName = kindName;
		}

		public String getKindName() {
			return kindName;
		}

		public Long getCount() {
			return count;
		}

		public Long getSize() {
			return size;
		}

		public Long getRootCount() {
			return rootCount;
		}

		public Long getRootSize() {
			return rootSize;
		}

		public Long getNonRootCount() {
			return nonRootCount;
		}

		public Long getNonRootSize() {
			return nonRootSize;
		}

		public void addCount(Long count) {
			this.count = this.count == null ? count : this.count + count;
		}

		public void addSize(Long size) {
			this.size = this.size == null ? size : this.size + size;
		}

		public void addRootCount(Long rootCount) {
			this.rootCount = this.rootCount == null ? rootCount : this.rootCount + rootCount;
		}

		public void addRootSize(Long rootSize) {
			this.rootSize = this.rootSize == null ? rootSize : this.rootSize + rootSize;
		}

		public void addNonRootCount(Long nonRootCount) {
			this.nonRootCount = this.nonRootCount == null ? nonRootCount : this.nonRootCount + nonRootCount;
		}

		public void addNonRootSize(Long nonRootSize) {
			this.nonRootSize = this.nonRootSize == null ? nonRootSize : this.nonRootSize + nonRootSize;
		}
	}
	
	/**
	 * update kind names for dropdown box
	 * 
	 * @param kindNames
	 */
	void initKindNames(Collection<String> kindNames);

	/**
	 * update namespace names for top dropdown box
	 * 
	 * @param namespaceNames
	 */
	void initNamespaceNames(Collection<String> namespaceNames);
	
	/**
	 * @param summary
	 */
	void updateSummary(Summary summary);
	
	/**
	 * @param breakdownList
	 */
	void updateNamespaceBreakdown(List<NamespaceBreakdown> breakdownList);
	
	/**
	 * @param breakdownList
	 */
	void updatePropertyTypeBreakdown(List<PropertyTypeBreakdown> breakdownList);
	
	/**
	 * update entity kind breakdown
	 * 
	 * @param breakdownList
	 */
	void updateKindBreakdown(List<KindBreakdown> breakdownList);
}